
#include "client.h"

int check_address_and_port(const char * ip, uint16_t port)
{
    // check port
    if (port < 0 || port > 65535) {

        // 端口超出范围
        return -1;
    }
    // get addr info
    {
        // // getaddrinfo()
        // struct addrinfo hints;
        // struct addrinfo * result;
        // bzero(&hints, sizeof(hints));
        // // hints.ai_family = AF_UNSPEC;    // ipv4 and ipv6
        // hints.ai_family = AF_INET;
        // hints.ai_socktype = SOCK_STREAM;   // tcp protocol
        // hints.ai_flags = AI_PASSIVE;       // 被动打开

        // // gethostbyaddr()
        // if(getaddrinfo(ip, "tcp", &hints, &result) != 0 || result == NULL) {

        //     // 调用getaddrinfo出错
        //     return -1;
        // }
        // freeaddrinfo(result);
        // return 0;
    }
    // gethostbyaddr
    {
        struct hostent * host;
        struct in_addr addr;
        sizeof(&addr, sizeof(addr));
        inet_pton(AF_INET, ip, &addr);

        host = gethostbyaddr((void*)&addr, sizeof(addr), AF_INET);
        if (host != NULL || gethostbynameinformation(ip) != NULL) {

            return 0;
        }
    }
    return -1;
}

struct hostent * gethostbynameinformation(const char * ip) {

    struct hostent * host = NULL;
    struct in_addr addr;
    sizeof(&addr, sizeof(addr));
    inet_pton(AF_INET, ip, &addr);

    host = gethostbyname(ip);
    if (host == NULL) {

        return NULL;
    }
    return host;
}

socket_t connect_to_server(const char * ip, uint16_t port)
{
    if (check_address_and_port(ip, port) != 0) {

        return -1;
    }
    socket_t sockfd = -1;
    do {
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) {
            // create socket error
            break;
        }
        struct hostent * host = gethostbynameinformation(ip);
        if (host == NULL) {

            sockfd = -1;
            break;
        }
        int connect_status = 0;
        SAI server_address;
        for (int index = 0; host->h_addr_list[index]; index++) {

            bzero(&server_address, sizeof(server_address));
            server_address.sin_family = AF_INET;
            server_address.sin_port   = htons(port);
            bcopy((void*)host->h_addr_list[index], &server_address.sin_addr, sizeof(struct in_addr));

            if (connect(sockfd, (SA*)&server_address, sizeof(server_address)) == 0) {

                connect_status = 1;
                break;
            }
        }
        if (connect_status == 1) {

            break;
        } else {

            sockfd = -1;
            break;
        }
    }while(0);
    return sockfd;
}

socket_t connect_to_server_int_help(const char * ip, uint16_t port) {

    return connect_to_server(ip, port);
}

socket_t connect_to_server_char_help(const char * ip, const char * port) {

    return connect_to_server(ip, atoi(port));
}